#!/bin/sh
# shellcheck shell=dash disable=SC2169 source=/dev/null
#
# Starts multimacd.
#

LOGLEVEL_RFD=5
CFG_TEMPLATE_DIR=/etc/config_templates
PIDFILE=/var/run/multimacd.pid
STEPS=10

[[ -r /var/hm_mode ]] && . /var/hm_mode

init() {
  # make sure /var/etc/multimacd.conf contains the correct
  # coprocessor device path
  sed "s|^Coprocessor Device Path = /dev/.*$|Coprocessor Device Path = ${HM_HMRF_DEVNODE}|" ${CFG_TEMPLATE_DIR}/multimacd.conf >/var/etc/multimacd.conf

  # make sure /dev/eq3loop exists
  if [[ ! -c /dev/eq3loop ]]; then
    # load eq3_char_loop kernel module
    modprobe eq3_char_loop

    # wait until /dev/eq3loop is ready to use
    for i in $(seq 1 ${STEPS}); do
      echo -n "."
      if head -c0 /dev/eq3loop >/dev/null 2>&1; then
        break
      fi
      sleep 1
    done
    if [[ ${i} -eq ${STEPS} ]]; then
      echo "ERROR: couldn't setup /dev/eq3loop"
      exit 2
    fi
  fi
}

waitStartupComplete() {
  for i in $(seq 1 ${STEPS}); do
    sleep 2
    echo -n "."
    MMDSTATUSPID=$(cat /var/status/multimacd.status 2>&1)
    MMDPID=$(pidof multimacd)
    if [[ "${MMDSTATUSPID}" == "${MMDPID}" ]]; then
      if [[ ! -c /dev/mmd_hmip ]] || [[ ! -c /dev/mmd_bidcos ]]; then
        echo -n "."
        # restart multimacd
        start-stop-daemon -K -q -p ${PIDFILE}
        sleep 2
        start-stop-daemon -S -N -15 -q -b -m -p ${PIDFILE} --exec /bin/multimacd -- -f /var/etc/multimacd.conf -l ${LOGLEVEL_RFD}
      else
        # wait until /dev/mmd_* devices are accessible
        for j in $(seq 1 ${STEPS}); do
          echo -n "."
          if head -c0 /dev/mmd_bidcos >/dev/null 2>&1 &&
             head -c0 /dev/mmd_hmip >/dev/null 2>&1; then
            break
          fi
          sleep 1
        done

        if [[ ${j} -eq ${STEPS} ]]; then
          echo "ERROR: couldn't setup /dev/mmd_* devices"
          exit 2
        else
          echo "OK"
        fi
        break
      fi
    fi
    if [[ ${i} -eq ${STEPS} ]]; then
      echo "ERROR"
    fi
  done
}

start() {
  echo -n "Starting multimacd: "

  # we only need multimacd+eq3loop if HMIP+HMRF is using the same device
  if [[ -n "${HM_HMIP_DEV}" ]] && [[ -n "${HM_HMRF_DEV}" ]] &&
     ( ( ! echo "${HM_HMIP_DEV}" | grep -q "HMIP-RFUSB" ) || [[ "${HM_HMRF_DEV}" != "HM-CFG-USB-2" ]] ); then

    # we need to check if the system allows changing real-time scheduling attributes or otherwise
    # multimacd startup will fail as it uses sched_setscheduler() to
    # raise the real-time priority for processing things with low latency
    if /usr/bin/chrt -f 10 echo >/dev/null 2>&1; then

      # run init function
      init

      # check if eq3loop is present
      if [[ -c /dev/eq3loop ]]; then
        # get the current syslog settings
        [[ -r /etc/config/syslog ]] && . /etc/config/syslog

        # adjust the oom score (which is inherited by start-stop-daemon)
        # to ensure that others are killed first in case of low memory situations
        echo -900 >/proc/$$/oom_score_adj 2>/dev/null

        # start multimacd with nice level -15 to increase
        # process priority
        start-stop-daemon -S -N -15 -q -b -m -p ${PIDFILE} --exec /bin/multimacd -- -f /var/etc/multimacd.conf -l ${LOGLEVEL_RFD}
        waitStartupComplete
      else
        echo "ERROR: /dev/eq3loop missing"
      fi
    else
      echo "ERROR: real-time scheduling test failed. CONFIG_RT_GROUP_SCHED not set or host kernel unable to utilize sched_setscheduler()"
    fi
  else
    echo "not required"
  fi
}

stop() {
  echo -n "Stopping multimacd: "
  if [[ -f "${PIDFILE}" ]]; then
    start-stop-daemon -K -q -p ${PIDFILE}
    rm -f ${PIDFILE}
    echo "OK"

    # make sure to unload eq3_char_loop which
    # is necessary for docker-based environments
    if [[ -c /dev/eq3loop ]]; then
      sleep 2 # wait to settle
      # load eq3_char_loop kernel module
      rmmod eq3_char_loop 2>/dev/null
    fi
  else
    echo "not started"
  fi
}

restart() {
  stop
  start
}

case "$1" in
  start)
    start
  ;;
  stop)
    stop
  ;;
  restart|reload)
    restart
  ;;
  *)
    echo "Usage: $0 {start|stop|restart}"
    exit 1
esac

exit 0
